<!--
 * @description: 控制对象属性编辑
 * @fileName: EntityEditDialog.vue
 * @author: ssr
 * @date: 2023-01-05 15:05:03
 * @version: V1.0.0
! -->
<script setup lang="ts">
import type { IControlItem } from "@@/apis/scn/type"
import type { FormInstance, FormRules } from "element-plus"
import { useCesiumStore } from "@/pinia/stores/cesium"
import { useScenarioStore } from "@/pinia/stores/scenario"
import { getControlInstanceById, isRepeatControlName, updateControlName } from "@@/apis/scn"
import mitter from "@@/utils/mitter"
import { ElMessage } from "element-plus"
import { isEmpty } from "lodash-es"
import { reactive, ref } from "vue"

// 状态和引用
const cesiumStore = useCesiumStore()
const scenarioStore = useScenarioStore()
const formState = reactive({
  entityName: ""
})
const formRef = ref<FormInstance>()
const dialogVisible = ref(false)
const loading = ref(false)
const state = reactive<{
  curId: string
}>({
  curId: ""
})

// 表单验证规则
const rules = reactive<FormRules>({
  entityName: [
    { required: true, message: "请输入名称", trigger: "blur" },
    { validator: handleValidator, trigger: "blur" }
  ]
})

// 显示对话框
async function handleShowDialog(id: string) {
  state.curId = id
  formState.entityName = ""

  // 查询实体信息
  await handleEntityInfo()
  dialogVisible.value = true
}

// 保存更新
async function handleConfirm() {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    loading.value = true

    const params = {
      id: state.curId,
      scnId: scenarioStore.scnId,
      name: formState.entityName
    }

    await updateControlName(params)
    ElMessage.success("更新成功")
    // 更新列表
    mitter.emit("updateSelectedControl")
    // 根据id获取控制对象实例
    const instance = scenarioStore.findControlInstanceById(state.curId)
    if (instance) {
      // 更新Cesium实体标签
      const drawingManager = cesiumStore.getCustomViewer.drawingManager
      if (drawingManager) {
        const entity = drawingManager.getById(instance.cesiumId)
        if (entity) {
          entity.label.text = formState.entityName
        }
      }
    }
    dialogVisible.value = false
  } catch (error) {
    console.error("更新控制对象名称失败:", error)
  } finally {
    loading.value = false
  }
}

// 根据id查询实体信息
async function handleEntityInfo() {
  if (isEmpty(state.curId)) return null

  try {
    const { data } = await getControlInstanceById(state.curId)

    const entityInfo: IControlItem = data
    formState.entityName = entityInfo.name
    return entityInfo
  } catch (error) {
    console.error("获取控制对象信息失败:", error)
    ElMessage.error("获取控制对象信息失败")
    return null
  }
}

// 取消
function handleCancel() {
  formRef.value?.resetFields()
  dialogVisible.value = false
}

// 名称验证器
async function handleValidator(_rule: any, value: string, callback: any) {
  if (!value) {
    callback(new Error("请输入名称"))
    return
  }

  try {
    const params = {
      id: state.curId,
      scnId: scenarioStore.scnId,
      name: value
    }

    const { data } = await isRepeatControlName(params)
    if (data) {
      callback(new Error("该名称已存在！"))
    } else {
      callback()
    }
  } catch (error) {
    console.error("验证名称失败:", error)
    callback(new Error("验证失败"))
  }
}

// 暴露方法给父组件
defineExpose({
  handleShowDialog
})
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    title="属性编辑"
    width="30%"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-form
      :model="formState"
      :rules="rules"
      ref="formRef"
      label-width="80px"
      label-position="right"
      status-icon
    >
      <el-form-item label="名称" prop="entityName">
        <el-input v-model="formState.entityName" placeholder="请输入名称" />
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="loading">
          确认
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

:deep(.el-dialog__body) {
  padding-top: 10px;
  padding-bottom: 10px;
}
</style>
